// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

// 状态
enum State {
    stand = 1,
    attack,
    hurt,
    dead
}
// 动画名称
enum Anima {
    idle = 'idle2',
    run = 'run',
    attack1 = 'attack1',
    hurt = 'hurt',
    dead = 'dead',
    
}

@ccclass
export default class NewClass extends cc.Component {

    // 生命值
    @property
    hp: number = 5;

    // 是否被攻击
    @property
    isHit: boolean = false;

    // 速度
    @property
    speed: number = 80;

    // 方向
    @property
    sp: cc.Vec2 = null;

    // enemy状态
    @property
    enemySate: State  = null;

    // enemy动画
    @property
    enemyAni: cc.Animation = null;

    // 动画状态
    @property
    annima:Anima  = null

    // 连击
    @property
    combo: number = 0;


    // 刚体在世界坐标下的(线性速度)
    @property
    lv: cc.Vec2  = null


    @property
    moveLeft: boolean = false;
    @property
    moveRight: boolean = false;

    @property
    tt:number = 0;

    // 玩家节点
    @property
    playerNode: cc.Node = null;



    // LIFE-CYCLE CALLBACKS:

    onLoad () {

        this.sp = cc.v2(0,0)

        this.speed = 80

        this.enemySate = State.stand

        this.annima = Anima.idle

        this.playerNode = cc.find('Canvas/bg/hero')

        // this.lv = this.node.getComponent(cc.RigidBody).linearVelocity

        this.enemyAni = this.node.getChildByName('body').getComponent(cc.Animation)
        

        this.enemyAni.on(cc.Animation.EventType.FINISHED, this.onFinishAnima, this)

        this.moveLeft = true

        
    }

    onDestroy() {
        // this.enemyAni.off(cc.Animation.EventType.FINISHED, this.onFinishAnima, this)
    }

    onFinishAnima(e: cc.Event.EventCustom, data:cc.AnimationState) {
        let aniName = data.name
        cc.log('动画结束', aniName)
        if(aniName == Anima.hurt) {
            this.hp --
            cc.log('current hp is', this.hp)

            this.isHit = false

            // 恢复stand
            this.enemySate = State.stand
            
    
            if(this.hp == 0) {
                this.enemySate = State.dead
                // 速度为0  延迟消失
                this.changeDirection(0)
                // 死亡动画
                this.setAnima(Anima.dead)
                setTimeout(()=>{
                    this.node.destroy()
                }, 1000)
                
            }
        }else if(aniName == Anima.attack1) {
            // 继续移动
            this.enemySate = State.stand
            // 清空记录的动画,避免不能连续攻击
            this.annima = null
        }
    }


    hurt():void{
        cc.log('hurt......')
        // 速度为0
        this.sp.x = 0
        this.setSpeed()

        this.isHit = true
        this.enemySate = State.hurt
        this.setAnima(Anima.hurt)
    }

    // start () {}

    update (dt:number) {


        this.tt += dt
        if(this.tt >= 0.3 && this.enemySate == State.stand) {
            this.enemyAction(dt)
            this.tt = 0
        }

        if (this.enemySate == State.stand) {
            this.move()
        }else if (this.enemySate == State.attack) {
            this.attack()
        }

        
    }


    // 移动
    move():void {
        let scaleX = Math.abs(this.node.getChildByName('body').scaleX)
        let annima = this.annima
        if (this.moveLeft) {
            // <--
            this.sp.x = 1
            this.node.scaleX = - scaleX
            annima = Anima.run
        }else if(this.moveRight){
            this.sp.x = -1
            this.node.scaleX = scaleX
            annima = Anima.run
        } else {
            this.sp.x = 0
            annima = Anima.idle
        }

        this.setSpeed()
        // 修改动画
        this.setAnima(annima)
    }

    // 攻击
    attack():void {
        this.sp.x = 0
        this.setSpeed()
        // 修改动画
        this.setAnima(Anima.attack1)
        
    }

    // 改变速度(向量)
    setSpeed():void {
        // 刚体
        let rigidBody = this.node.getComponent(cc.RigidBody)
        // 刚体的线性速度
        this.lv = rigidBody.linearVelocity
        // 速度和方向
        if (this.sp.x) {
            this.lv.x = this.sp.x * this.speed;
        } else {
            this.lv.x = 0
        }
        // 速度赋值
        rigidBody.linearVelocity = this.lv
    }

    /**
     * 播放新动画
     * @param animiat 
     */
    setAnima(animiat: Anima):void {
        if(!animiat || this.annima == animiat) {
            return
        }
        cc.log('动画改变 old {}, new {}',this.annima, animiat)
        this.annima = animiat
        // 播放新动画
        // cc.log('当前播放动画:' + animiat)
        this.enemyAni.play(animiat)
    }

    // 敌人行为
    enemyAction(tt:number) {
        let p_position = this.playerNode.position
        let e_position = this.node.position
        let distance = cc.Vec2.distance(p_position, e_position)
        
        // x相隔距离
        let v = p_position.sub(e_position)

        cc.log('current distance is ', v.x)
        if (distance <= 30) {
            cc.log('attack')
            // 先调整方向, 面向玩家
            this.changeDirection2(v.x)
            // 静止
            this.changeDirection(0)

            this.enemySate = State.attack

        }else if (distance <= 150) {
            cc.log('追击')
            this.changeDirection(v.x)

        }else{
            cc.log('随机走 巡逻')
            this.changeDirection(Math.random() > 0.5 ? 1 : -1)
        }

    }

    /**
     * 改变移动方向
     * @param type > 0 向左 < 0 向右
     */
    changeDirection(type:number):void{
        if (type > 0) {
            this.moveLeft = true
            this.moveRight = false
        }else if(type < 0){
            this.moveLeft = false
            this.moveRight = true
        }else{
            this.moveLeft = false
            this.moveRight = false
        }
    }

    /**
     * 直接调整它方向(用于持续攻击)
     * @param type 
     */
    changeDirection2(type:number):void{
        let scaleX = Math.abs(this.node.scaleX)
        if (type > 0) {
            this.node.scaleX = -scaleX
        }else if(type < 0){
            this.node.scaleX = scaleX
        }else{
            // 完全重合了  什么也不做
        }
    }
}
